import { type Compiler, type Compilation } from "@rspack/core";
import fs from "node:fs";
export interface ErudaPluginOptions {
  debug?: boolean;
}

export class ErudaPlugin {
  private debug: boolean;

  constructor(options: ErudaPluginOptions = {}) {
    this.debug = options.debug ?? false;
  }

  apply(compiler: Compiler): void {
    compiler.hooks.compilation.tap(
      "ErudaPlugin",
      (compilation: Compilation) => {
        const HtmlRspackPlugin =
          compiler.rspack?.HtmlRspackPlugin ||
          compiler.webpack?.HtmlRspackPlugin;
        if (!HtmlRspackPlugin) return;
        HtmlRspackPlugin.getCompilationHooks(
          compilation
        ).alterAssetTags.tapPromise("ErudaPlugin", async (pluginArgs) => {
          if (!this.debug) return pluginArgs;

          // 读取依赖包文件
          const jsQRContent = fs.readFileSync(
            require.resolve("jsqr/dist/jsQR.js"),
            "utf-8"
          );
          const erudaContent = fs.readFileSync(
            require.resolve("eruda"),
            "utf-8"
          );
          // 注入初始化和功能代码
          const initScript = `(function(){eruda.init();eruda.add({name:'DevPanel',init($el){this._$el=$el;const devServer=localStorage.getItem('dev_server')||'';this._$el.html(\`<div class="dev-panel"><input type="text"value="\${devServer}"placeholder="输入要跳转的地址"/><button onclick="location.href=this.previousElementSibling.value">跳转</button><button id="scanBtn">扫码跳转</button></div>\`);const style=document.createElement('style');style.textContent=\`.dev-panel{padding:15px}.dev-panel input{width:100%;padding:8px;margin-bottom:10px;border:1px solid#ddd;border-radius:4px}.dev-panel button{width:100%;padding:8px;margin-bottom:10px;border:none;border-radius:4px;background:#409eff;color:white;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px}.dev-panel button:last-child{background:#67c23a}\`;this._$el.append(style);this._$el.find('input').on('change',e=>localStorage.setItem('dev_server',e.target.value));this._$el.find('#scanBtn').on('click',this._handleScan.bind(this))},async _handleScan(){try{const video=document.createElement('video');video.setAttribute('playsinline',true);const stream=await navigator.mediaDevices.getUserMedia({video:{facingMode:'environment'}});video.srcObject=stream;const scanner=document.createElement('div');scanner.innerHTML='<div class="scanner"><div class="viewport"></div><button class="close"></button></div>';document.body.appendChild(scanner);const style=document.createElement('style');style.textContent=\`.scanner{position:fixed;inset:0;background:rgba(0,0,0,0.8);z-index:1000000}.viewport{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:280px;height:280px;border:1px solid rgba(255,255,255,0.3);border-radius:16px;overflow:hidden}.close{position:fixed;left:50%;top:50%;transform:translate(-50%,160px);width:36px;height:36px;background:rgba(255,255,255,0.9);border:none;border-radius:50%;cursor:pointer}\`;scanner.appendChild(style);video.style.cssText='position: fixed; inset: 0; width: 100%; height: 100%; object-fit: cover;';scanner.querySelector('.viewport').prepend(video);eruda.hide();await video.play();const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=video.videoWidth;canvas.height=video.videoHeight;const cleanup=()=>{stream?.getTracks().forEach(track=>track.stop());scanner?.remove();eruda?.show()};scanner.querySelector('.close').onclick=cleanup;window.addEventListener('visibilitychange',()=>document.hidden&&cleanup(),{once:true});const scan=setInterval(()=>{if(document.hidden)return;ctx.drawImage(video,0,0);const code=jsQR(ctx.getImageData(0,0,canvas.width,canvas.height).data,canvas.width,canvas.height);if(code?.data?.startsWith('http')){cleanup();localStorage.setItem('dev_server',code.data);location.href=code.data}},200);window.addEventListener('beforeunload',()=>{clearInterval(scan);cleanup()},{once:true})}catch(err){alert('无法访问摄像头，请确保已授予相关权限')}}})})();`;

          pluginArgs.assetTags.scripts.push(
            {
              tagName: "script",
              voidTag: false,
              innerHTML: jsQRContent,
              attributes: {},
            },
            {
              tagName: "script",
              voidTag: false,
              innerHTML: erudaContent,
              attributes: {},
            },
            {
              tagName: "script",
              voidTag: false,
              innerHTML: initScript,
              attributes: {},
            }
          );
          return pluginArgs;
        });
      }
    );
  }
}

export default ErudaPlugin;
